
package cz.czu.pef.DataModelling.utils;

import java.util.logging.Level;
import java.util.logging.Logger;

import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Required;
import org.springframework.orm.jpa.persistenceunit.MutablePersistenceUnitInfo;
import org.springframework.orm.jpa.persistenceunit.PersistenceUnitPostProcessor;


/**
* Injects the dataSource in the {@link javax.persistence.spi.PersistenceUnitInfo}
* according to the chosen mode. By default, JTA is not enabled and the dataSource
* is injected as a non-jta aware data source. If the {@link #setJtaEnabled(boolean)}
* flag is set to true the dataSource is injected as a jta-aware data source.
*
* @author Stephane Nicoll
*/
public class JtaPersistenceUnitPostProcessor implements PersistenceUnitPostProcessor
{

  private final Logger logger = Logger.getLogger(JtaPersistenceUnitPostProcessor.class.getName());

  private DataSource dataSource;
  private boolean jtaEnabled = false;

  /**
   * Enriches the PersistenceUnitInfo read from the persistence.xml
   * configuration file according to the jtaEnabled flag. Registers
   * the dataSource as a jta data source if it is true or
   * as a regular, non-jta data source otherwise.
   */
  public void postProcessPersistenceUnitInfo(MutablePersistenceUnitInfo mutablePersistenceUnitInfo)
  {
    if (jtaEnabled)
    {
      if (logger.isLoggable(Level.FINE))
        logger.log(Level.FINE, "Enriching the persistence unit info with the jta aware data source.");
      mutablePersistenceUnitInfo.setJtaDataSource(dataSource);
      mutablePersistenceUnitInfo.setTransactionType(PersistenceUnitTransactionType.JTA);
    }
    else
    {
      if (logger.isLoggable(Level.FINE))
        logger.log(Level.FINE, "Enriching the persistence unit info with the non-jta aware data source.");
      mutablePersistenceUnitInfo.setNonJtaDataSource(dataSource);
      mutablePersistenceUnitInfo.setTransactionType(PersistenceUnitTransactionType.RESOURCE_LOCAL);
    }
  }

  /**
   * Sets the {@link DataSource} to be used by the entity manager factory
   *
   * @param dataSource the data source to use
   */
  @Required
  public void setDataSource(DataSource dataSource)
  {
    this.dataSource = dataSource;
  }

  /**
   * Specify if the data source should be injected as a jta-aware dataSource
   * in the entity manager.
   *
   * @param jtaEnabled true to enable jta support
   */
  public void setJtaEnabled(boolean jtaEnabled)
  {
    this.jtaEnabled = jtaEnabled;
  }

}